const std = @import("std");
const Allocator = std.mem.Allocator;

const Event = @import("map/event.zig");
const Index = @import("map/index.zig");

const Map = @This();

allocator: Allocator,
rand: *const std.Random,

index: *Index,
event: *Event,

width: u32 = 800,
height: u32 = 480,

pub fn init(width: u32, height: u32, rand: *const std.Random, allocator: Allocator) *@This() {
    const item = allocator.create(@This()) catch @panic("Out of memory");

    item.allocator = allocator;
    item.rand = rand;
    item.width = width;
    item.height = height;

    item.index = Index.init(item);
    item.event = Event.init(item);

    return item;
}

pub fn deinit(self: *@This()) void {
    self.event.deinit();
    self.index.deinit();

    self.allocator.destroy(self);
}

pub fn randX(self: *const @This()) f32 {
    return @floatFromInt(self.rand.intRangeAtMost(u32, 0, self.width - 1));
}

pub fn randY(self: *const @This()) f32 {
    return @floatFromInt(self.rand.intRangeAtMost(u32, 0, self.height - 1));
}

pub fn action(self: *@This()) void {
    self.event.gen();

    for (self.index.list.items) |block| {
        block.prepare();
    }

    for (self.index.list.items) |block| {
        block.do();
    }

    for (self.index.list.items) |block| {
        block.post();
    }
}

pub fn draw(self: *@This()) void {
    for (self.index.list.items) |block| {
        block.draw();
    }
}
